package com.punch.user.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punch.common.dto.login.WXUserDTO;
import com.punch.common.dto.user.teacher.TeacherAuditDTO;
import com.punch.common.dto.user.teacher.TeacherDTO;
import com.punch.common.dto.user.teacher.TeacherImportDTO;
import com.punch.common.dto.user.user.RedisUserDTO;
import com.punch.common.enums.user.role.UserRoleEnum;
import com.punch.common.enums.user.user.AuditStatusEnum;
import com.punch.common.enums.user.user.UserTypeEnum;
import com.punch.common.exception.BusinessException;
import com.punch.common.feign.FeignAreaService;
import com.punch.common.model.LoginUser;
import com.punch.common.page.PageInfo;
import com.punch.common.query.user.teacher.TeacherQueryInfo;
import com.punch.common.simple.redis.utils.UserUtil;
import com.punch.common.tools.BasePage;
import com.punch.common.utils.HulToolExcelUtil;
import com.punch.common.utils.ImageUtil;
import com.punch.common.utils.PhoneUtils;
import com.punch.common.utils.StringUtil;
import com.punch.common.vo.user.teacher.SimpleTeacherVO;
import com.punch.common.vo.user.teacher.TeacherPageVO;
import com.punch.common.vo.user.teacher.TeacherVO;
import com.punch.user.exception.UserExceptionEnum;
import com.punch.user.mapper.SysTeacherMapper;
import com.punch.user.model.SysAuditLog;
import com.punch.user.model.SysTeacher;
import com.punch.user.model.SysUser;
import com.punch.user.service.AuditLogService;
import com.punch.user.service.TeacherService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;


@Service
@Slf4j
public class TeacherServiceImpl extends ServiceImpl<SysTeacherMapper, SysTeacher> implements TeacherService {

    @Resource
    private AuditLogService auditLogService;

    @Resource
    private FeignAreaService feignAreaService;

    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 教师分页
     *
     * @param queryInfo 查询条件
     * @return PageInfo<TeacherPageVO>
     */
    @Override
    public PageInfo<TeacherPageVO> queryPage(TeacherQueryInfo queryInfo) {
        //机构/学校 查找自己创建的教师
        if (queryInfo.getCurrentRoleId() == UserRoleEnum.ORGAN.getCode() || queryInfo.getCurrentRoleId() == UserRoleEnum.SCHOOL.getCode()) {
            queryInfo.setCreateId(UserUtil.getLoginUserId());
        }
        return BasePage.queryBasePage(queryInfo, params -> baseMapper.queryCount(params),
                params -> baseMapper.queryList(params));
    }

    /**
     * 获取教师详情
     *
     * @param teacherId 老师id
     * @return TeacherVO
     */
    @Override
    public TeacherVO getTeacher(Long teacherId) {
        SysTeacher sysTeacher = getById(teacherId);
        TeacherVO teacherVO = new TeacherVO();
        BeanUtils.copyProperties(sysTeacher, teacherVO);
        //头像
        if (StrUtil.isNotEmpty(sysTeacher.getHeadImgUrl())) {
            teacherVO.setHeadImgUrl(ImageUtil.addPrefix(sysTeacher.getHeadImgUrl()));
        }
        //身份证照片
        if (StrUtil.isNotEmpty(sysTeacher.getIdCardUrl())) {
            teacherVO.setIdCardUrl(ImageUtil.addPrefix(sysTeacher.getIdCardUrl()));
        }
        //教师资格证照片
        if (StrUtil.isNotEmpty(sysTeacher.getCertificationUrl())) {
            teacherVO.setCertificationUrl(ImageUtil.addPrefix(sysTeacher.getCertificationUrl()));
        }
        teacherVO.setTeacherId(sysTeacher.getId());
        return teacherVO;
    }

    /**
     * 新增教师
     *
     * @param teacherDTO 教师表单
     * @return teacherId
     */
    @Override
    public Long saveTeacher(TeacherDTO teacherDTO) {
        verifyMobile(teacherDTO.getMobile());
        verifyAccount(teacherDTO.getMobile(), 0L);
        SysTeacher sysTeacher = new SysTeacher();
        BeanUtils.copyProperties(teacherDTO, sysTeacher);
        RedisUserDTO loginUser = UserUtil.getLoginUser();
        Integer currentRoleId = loginUser.getRoleId();//查看当前用户角色id
        //如果是机构新增,则把教师的审批状态改成待提交,需要给教育局审核
        if (currentRoleId == UserRoleEnum.ORGAN.getCode()) {
            sysTeacher.setAuditStatus(AuditStatusEnum.TO_AUDIT.getCode());
        }
        //设置教师的role与地区
        sysTeacher.setRoleId(currentRoleId);
        String createName = loginUser.getUsername();
        //设置创建人名称（所属机构）
        sysTeacher.setCreateName(createName);
        Integer areaId = loginUser.getAreaId();
        sysTeacher.setAreaId(areaId);
        String parentIds = feignAreaService.getParentIds(areaId);
        sysTeacher.setAllAreaIds(parentIds + "," + areaId);
        sysTeacher.setAreaName(loginUser.getAreaName());
        sysTeacher.setCreateId(loginUser.getUserId());
        //处理图片
        if (StrUtil.isNotEmpty(teacherDTO.getHeadImgUrl())) {
            sysTeacher.setHeadImgUrl(ImageUtil.removePrefix(teacherDTO.getHeadImgUrl()));
        }
        if (StrUtil.isNotEmpty(teacherDTO.getIdCardUrl())) {
            sysTeacher.setIdCardUrl(ImageUtil.removePrefix(teacherDTO.getIdCardUrl()));
        }
        if (StrUtil.isNotEmpty(teacherDTO.getCertificationUrl())) {
            sysTeacher.setCertificationUrl(ImageUtil.removePrefix(teacherDTO.getCertificationUrl()));
        }
        sysTeacher.setPassword(passwordEncoder.encode("123456"));
        boolean flag = save(sysTeacher);
        if (!flag) {
            throw new BusinessException(UserExceptionEnum.DATA_INSERT_EXCEPTION);
        }
        return sysTeacher.getId();
    }

    /**
     * 修改教师信息
     *
     * @param teacherDTO 教师表单
     */
    @Override
    public void updateTeacher(TeacherDTO teacherDTO) {
        verifyMobile(teacherDTO.getMobile());
        verifyAccount(teacherDTO.getMobile(), teacherDTO.getTeacherId());
        SysTeacher sysTeacher = new SysTeacher();
        BeanUtils.copyProperties(teacherDTO, sysTeacher);
        sysTeacher.setId(teacherDTO.getTeacherId());
        //处理图片
        if (StrUtil.isNotEmpty(teacherDTO.getHeadImgUrl())) {
            sysTeacher.setHeadImgUrl(ImageUtil.removePrefix(teacherDTO.getHeadImgUrl()));
        } else {
            sysTeacher.setHeadImgUrl("");
        }
        if (StrUtil.isNotEmpty(teacherDTO.getIdCardUrl())) {
            sysTeacher.setIdCardUrl(ImageUtil.removePrefix(teacherDTO.getIdCardUrl()));
        } else {
            sysTeacher.setIdCardUrl("");
        }
        if (StrUtil.isNotEmpty(teacherDTO.getCertificationUrl())) {
            sysTeacher.setCertificationUrl(ImageUtil.removePrefix(teacherDTO.getCertificationUrl()));
        } else {
            sysTeacher.setCertificationUrl("");
        }
        boolean flag = updateById(sysTeacher);
        if (!flag) {
            throw new BusinessException(UserExceptionEnum.TEACHER_NOT_EXIST);
        }
    }

    /**
     * 教师审核
     *
     * @param teacherAuditDTO 教师审核表单
     */
    @Override
    public void auditTeacher(TeacherAuditDTO teacherAuditDTO) {
        //当前登录用户角色id
        RedisUserDTO redisUserDTO = UserUtil.getLoginUser();
        Integer currentRoleId = redisUserDTO.getRoleId();
        SysTeacher sysTeacher = getById(teacherAuditDTO.getTeacherId());
        Optional.ofNullable(sysTeacher).orElseThrow(() -> new BusinessException(UserExceptionEnum.TEACHER_NOT_EXIST));
        verifyStatus(teacherAuditDTO.getAuditStatus(), sysTeacher.getAuditStatus(), currentRoleId);
        SysTeacher bean = new SysTeacher();
        bean.setId(teacherAuditDTO.getTeacherId());
        //如果是机构,查看且没有审核成功,教师提交审核状态为(机构待审核提交),确保机构用户在教师列表查询不到该数据
        if (currentRoleId.equals(UserRoleEnum.ORGAN.getCode()) && !redisUserDTO.getAuditStatus().equals(AuditStatusEnum.PASSED.getCode())) {
            bean.setAuditStatus(AuditStatusEnum.ORG_UN_AUDIT_COMMIT.getCode());
        } else {
            bean.setAuditStatus(teacherAuditDTO.getAuditStatus());
        }
        updateById(bean);
        fullAuditLog(teacherAuditDTO);
    }

    /**
     * 教师下拉列表
     *
     * @param teacherName
     * @param teacherId
     * @return List<SimpleCourseVO>
     * @author xiaol
     * @since 2020/7/23
     */
    @Override
    public List<SimpleTeacherVO> listTeacherSelect(String teacherName, Long teacherId) {
        Long currentUid = UserUtil.getLoginUser().getUserId();
        if (teacherId != null && teacherId.intValue() != 0) {
            //查找该课程的创建者
            currentUid = getById(teacherId).getCreateId();
        }
        QueryWrapper<SysTeacher> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysTeacher::getEnabled, 1)
                .eq(SysTeacher::getAuditStatus, AuditStatusEnum.PASSED.getCode())
                .eq(SysTeacher::getCreateId, currentUid);
        List<SysTeacher> list = list(queryWrapper);
        List<SimpleTeacherVO> retList = new ArrayList<>();
        list.forEach(sysTeacher -> {
            SimpleTeacherVO simpleTeacherVO = new SimpleTeacherVO();
            simpleTeacherVO.setTeacherId(sysTeacher.getId());
            simpleTeacherVO.setTeacherName(sysTeacher.getName());
            retList.add(simpleTeacherVO);
        });
        return retList;
    }

    /**
     * 教师启用/停用
     *
     * @param teacherId 教师id
     */
    @Override
    public void enableTeacher(Long teacherId) {
        SysTeacher sysTeacherEX = getById(teacherId);
        if (sysTeacherEX == null) {
            throw new BusinessException(UserExceptionEnum.TEACHER_NOT_EXIST);
        }
        SysTeacher updateTeacher = new SysTeacher();
        //启用变成停用
        if (sysTeacherEX.getEnabled() == 1) {
            updateTeacher.setEnabled(0);
        }
        //停用变成启用
        if (sysTeacherEX.getEnabled() == 0) {
            updateTeacher.setEnabled(1);
        }
        updateTeacher.setId(teacherId);
        updateById(updateTeacher);
    }

    /**
     * 根据用openId获取用户教师信息
     *
     * @param openId 小程序openId
     * @return LoginUser
     */
    @Override
    public LoginUser getFeignTeacherByOpenId(String openId) {
        QueryWrapper<SysTeacher> queryWrapper = new QueryWrapper<>();
        //获取机构下的教师
        queryWrapper.lambda().eq(SysTeacher::getOpenId, openId).eq(SysTeacher::getRoleId, UserRoleEnum.ORGAN.getCode());
        SysTeacher sysTeacher = getOne(queryWrapper);
        LoginUser loginUser = new LoginUser();
        if (sysTeacher == null) {
            loginUser.setUserId(0L);
        } else {
            loginUser.setUserId(sysTeacher.getId());
        }
        return loginUser;
    }

    @Override
    public LoginUser getFeignTeacherByMobile(String mobile) {
        QueryWrapper<SysTeacher> queryWrapper = new QueryWrapper<>();
        //获取机构下的教师
        queryWrapper.lambda().eq(SysTeacher::getMobile, mobile).eq(SysTeacher::getRoleId, UserRoleEnum.ORGAN.getCode());
        SysTeacher sysTeacher = getOne(queryWrapper);
        LoginUser loginUser = new LoginUser();
        if (sysTeacher == null) {
            loginUser.setUserId(0L);
        } else {
            loginUser.setEnabled(true);
            loginUser.setPassword(sysTeacher.getPassword());
            loginUser.setUsername(sysTeacher.getName());
            loginUser.setUserId(sysTeacher.getId());
        }
        return loginUser;
    }

    /**
     * 进行注册,不存在则注册,存在则返回
     *
     * @param wxUserDTO 微信用户表单
     */
    @Override
    public boolean saveFeignTeacher(WXUserDTO wxUserDTO) {
        QueryWrapper<SysTeacher> queryWrapper = new QueryWrapper<>();
        //根据手机号码查看教师存不存在
        queryWrapper.lambda().eq(SysTeacher::getMobile, wxUserDTO.getMobile()).eq(SysTeacher::getRoleId, UserRoleEnum.ORGAN.getCode());
        SysTeacher sysTeacherEX = getOne(queryWrapper);
        if (sysTeacherEX == null) {
            return false;
        }
        Long teacherId = sysTeacherEX.getId();
        //根据openId获取家长信息
        queryWrapper.clear();
        queryWrapper.lambda().eq(SysTeacher::getOpenId, wxUserDTO.getOpenId());
        sysTeacherEX = getOne(queryWrapper);
        //不存在则注册
        if (sysTeacherEX == null) {
            SysTeacher sysTeacher = new SysTeacher();
            sysTeacher.setOpenId(wxUserDTO.getOpenId());
            sysTeacher.setId(teacherId);
            updateById(sysTeacher);
        }
        return true;
    }

    /**
     * 教师导入
     *
     * @param file 文件
     * @return string
     */
    @Override
    public void importTeacher(MultipartFile file) {
        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            Map<String, String> headerAlias = HulToolExcelUtil.createExcelHeader(TeacherImportDTO.class);
            reader.setHeaderAlias(headerAlias);
            List<TeacherImportDTO> importTeacherList = reader.readAll(TeacherImportDTO.class);
            List<SysTeacher> insertList = new ArrayList<>();
            RedisUserDTO loginUser = UserUtil.getLoginUser();
            importTeacherList.forEach(teacherImportDTO -> {
                SysTeacher sysTeacher = new SysTeacher();
                sysTeacher.setName(StringUtil.replaceBlank(teacherImportDTO.getName()));
                sysTeacher.setMobile(StringUtil.replaceBlank(teacherImportDTO.getMobile()));
                int sex;
                if ("女".equals(StringUtil.replaceBlank(teacherImportDTO.getSex()))) {
                    sex = 0;
                } else if ("男".equals(StringUtil.replaceBlank(teacherImportDTO.getSex()))) {
                    sex = 1;
                } else {
                    sex = 2;
                }
                sysTeacher.setAreaId(loginUser.getAreaId());
                sysTeacher.setAreaName(loginUser.getAreaName());
                sysTeacher.setCreateName(loginUser.getUsername());
                sysTeacher.setCreateId(loginUser.getUserId());
                sysTeacher.setSex(sex);
                if (loginUser.getRoleId() == 3) {
                    sysTeacher.setAuditStatus(AuditStatusEnum.TO_AUDIT.getCode());
                }
                insertList.add(sysTeacher);
            });
            saveBatch(insertList);
        } catch (IOException e) {
            log.error("读取文件错误:{}", e.getMessage());
        }
    }

    /**
     * 获取教师审批失败信息
     *
     * @param teacherId 教师id
     * @return string
     */
    @Override
    public String getTeacherAuditMessage(Long teacherId) {
        QueryWrapper<SysAuditLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysAuditLog::getUserId, teacherId).orderByDesc(SysAuditLog::getUpdateTime).last("limit 1");
        SysAuditLog sysAuditLog = auditLogService.getOne(queryWrapper);
        return sysAuditLog.getRemarks();

    }

    /**
     * 修改机构未审核状态下提交的教师
     *
     * @param userId 机构id
     */
    @Override
    public void updateUnAuditCommit(Long userId) {
        getBaseMapper().updateUnAuditCommit(userId);
    }

    @Override
    public void handlerTeacherArea() {
        List<SysTeacher> list = list();
        list.forEach((t) -> {
            String parentIds = feignAreaService.getParentIds(t.getAreaId());
            SysTeacher sysTeacher = new SysTeacher();
            sysTeacher.setAllAreaIds(parentIds + "," + t.getAreaId());
            sysTeacher.setId(t.getId());
            updateById(sysTeacher);
        });
    }

    /**
     * 删除教师
     *
     * @param teacherId 教师id
     */
    @Override
    public void deleteTeacher(Long teacherId) {
        //应该有点业务控制把,暂时空着 todo
        boolean flag = removeById(teacherId);
        if (!flag) {
            throw new BusinessException(UserExceptionEnum.TEACHER_NOT_EXIST);
        }
    }


    /**
     * 校验教师账号
     *
     * @param mobile    手机号码
     * @param teacherId 教师id
     */
    private void verifyAccount(String mobile, Long teacherId) {
        QueryWrapper<SysTeacher> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysTeacher::getMobile, mobile);
        if (teacherId != null && teacherId > 0) {
            queryWrapper.lambda().notIn(SysTeacher::getId, teacherId);
        }
        SysTeacher sysTeacher = getOne(queryWrapper);
        if (sysTeacher != null) {
            throw new BusinessException(1, "该教师手机号已存在，请检查手机号");
        }
    }

    private void fullAuditLog(TeacherAuditDTO teacherAuditDTO) {
        SysAuditLog bean = new SysAuditLog();
        bean.setAuditStatus(teacherAuditDTO.getAuditStatus());
        bean.setAuditTime(LocalDateTime.now());
        bean.setType(UserTypeEnum.ORGAN.getCode());
        bean.setUserId(teacherAuditDTO.getTeacherId());
        bean.setAuditor(UserUtil.getLoginUserId());
        bean.setRemarks(teacherAuditDTO.getRemarks());
        auditLogService.save(bean);
    }

    /**
     * 验证手机号码
     *
     * @param mobile 手机号码
     */
    private void verifyMobile(String mobile) {
        if (!PhoneUtils.isPhone(mobile)) {
            throw new BusinessException(1, "手机号格式错误");
        }
    }


    /**
     * @param newStatus     即将更改状态
     * @param oldStatus     本身状态
     * @param currentRoleId 当前用户角色id
     */
    private void verifyStatus(Integer newStatus, Integer oldStatus, Integer currentRoleId) {
        //判断当前用户是否是运营人员还是机构,机构只能提交教师 运营人员审核教师，需要做验证
        if (!(currentRoleId == UserRoleEnum.MANAGER.getCode() || currentRoleId == UserRoleEnum.ORGAN.getCode() || currentRoleId == UserRoleEnum.ADMIN.getCode())) {
            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "只有运营/机构才能进行审核操作");
        }
        //不做太多控制状态

        //2者一致,说明状态错误
        if (oldStatus.equals(newStatus)) {
            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "审核状态错误");
        }
//        //已经审核不能在审核
//        if (oldStatus == AuditStatusEnum.PASSED.getCode()) {
//            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "该机构已审核");
//        }
//
//        //0状态说明机构还没提交该老师
//        if (oldStatus == AuditStatusEnum.TO_AUDIT.getCode()) {
//            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "该机构暂未提交审核");
//        }
    }
}
